package com.site.blog.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.PutObjectResult;
import com.site.blog.constants.HttpStatusEnum;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author :CodingFarmer_码农  Connor(康纳)_郭
 * @date : 20:40 20.7.2
 * @Company : http://www.gskj.com
 * @Version : 1.0
 * 公共方法类
 */
@Slf4j
public class MTUtils {

    /**
     * 专门负责上传文件到OSS服务器的工具方法
     *
     * @param endpoint        OSS参数
     * @param accessKeyId     OSS参数
     * @param accessKeySecret OSS参数
     * @param inputStream     要上传的文件的输入流
     * @param bucketName      OSS参数
     * @param bucketDomain    OSS参数
     * @param originalName    要上传的文件的原始文件名
     * @return 包含上传结果以及上传的文件在OSS上的访问路径
     */
    public static Result uploadFileToOss(String endpoint, String accessKeyId, String accessKeySecret,
                                         InputStream inputStream, String bucketName, String bucketDomain, String originalName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 生成上传文件的目录
        String folderName = new SimpleDateFormat("yyyy/MM/dd").format(new Date());

        // 生成上传文件在OSS服务器上保存时的文件名
        // 原始文件名：beautfulgirl.jpg
        // 生成文件名：wer234234efwer235346457dfswet346235.jpg
        // 使用UUID生成文件主体名称
        String fileMainName = UUID.randomUUID().toString().replace("-", "");

        // 从原始文件名中获取文件扩展名
        String extensionName = originalName.substring(originalName.lastIndexOf("."));

        // 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
        String objectName = folderName + "/" + fileMainName + extensionName;

        try {
            // 调用OSS客户端对象的方法上传文件并获取响应结果数据
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);

            // 从响应结果中获取具体响应消息
            ResponseMessage responseMessage = putObjectResult.getResponse();

            // 根据响应状态码判断请求是否成功
            if (responseMessage == null) {

                // 拼接访问刚刚上传的文件的路径
                String ossFileAccessPath = bucketDomain + "/" + objectName;

                // 当前方法返回成功

                return new Result(HttpStatusEnum.OK.getStatus(), ossFileAccessPath);
            } else {
                // 获取响应状态码
                int statusCode = responseMessage.getStatusCode();

                // 请求没有成功，获取错误消息
                String errorMessage = responseMessage.getErrorResponseAsString();

                // 当前方法返回失败
                Map<String, Object> map = new HashMap<>();
                map.put("statusCode", statusCode);
                map.put("errorMessage", errorMessage);
//                return ResultGenerator.genFailResult("上传图片至oss失败");
                return new Result(HttpStatusEnum.INTERNAL_SERVER_ERROR.getStatus(), HttpStatusEnum.INTERNAL_SERVER_ERROR.getContent());
            }
        } catch (Exception e) {
            e.printStackTrace();

            // 当前方法返回失败
            return new Result(HttpStatusEnum.INTERNAL_SERVER_ERROR.getStatus(), HttpStatusEnum.INTERNAL_SERVER_ERROR.getContent());
        } finally {
            if (ossClient != null) {
                // 关闭OSSClient。
                ossClient.shutdown();
            }
        }
    }

    /***
     *
     * 使用MD5 加密 数据
     *
     * @param source 要加密的数据
     * @return 加密后的结果
     *
     */
    public static String Md5Encipherment(String source) {
        // 1.非空判断
        if (null == source || source.length() == 0) {
            // 2.抛出
            throw new RuntimeException("准备加密的 source 为空！");
        }
        try {
            // 3.获取 MessageDigest对象
            String algorithm = "md5";
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);

            // 4.获取铭文字符串 字节数组
            byte[] input = source.getBytes();
            // 5.加密
            byte[] output = messageDigest.digest(input);

            // 6.创建BigInteger对象
            int signum = 1;
            BigInteger bigInteger = new BigInteger(signum, output);

            // 7.按照16进制将BigInteger转换为String
            int radix = 16;
            String string = bigInteger.toString(radix);
            return string;

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 因为项目使用Nginx 端口映射转发，获取ip需要处理下。
     *
     * @param request
     * @return
     */
    public static String getip(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        log.info("x-forwarded-for ip: " + ip);

        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if (ip.indexOf(",") != -1) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
            log.info(("Proxy-Client-IP ip: " + ip));
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
            log.info(("WL-Proxy-Client-IP ip: " + ip));
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
            log.info("HTTP_CLIENT_IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            log.info("HTTP_X_FORWARDED_FOR ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
            log.info("X-Real-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            log.info("getRemoteAddr ip: " + ip);
        }
        log.info("获取客户端ip: " + ip);
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    public static void main(String[] args) throws FileNotFoundException {

//        String filePaht = "2020032910510452802.jpg";
//        InputStream inputStream = new FileInputStream(filePaht);
//
//
//        String domain = "http://moster0506.oss-cn-shanghai.aliyuncs.com";
//        String point = "http://oss-cn-shanghai.aliyuncs.com";
//        String keyid = "LTAI4G5VAxtZAb5cZCUQCXfQ";
//        String keysecret = "ktIxiT9knB6yeKAdhY3cyojZTYNbOi";
//        String bucketname = "moster0506";
//
//        MTUtils.uploadFileToOss(point, keyid,keysecret , inputStream, bucketname, domain, "0702.jpg");

        //e10adc3949ba59abbe56e057f20f883e
//        System.out.println(Md5Encipherment("123456"));
    }
}
